package com.dlg.commons.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

/**
 * 日期处理工具类
 *
 * @author xpp
 * @date 2017年3月24日 上午10:20:49
 */

public class JodaTimeUtils {

    /**
     * 获取指定年月日时分的Date
     *
     * @author xpp
     * @date 2017年3月24日 上午10:40:34
     */
    public static Date getDate(short year, short month, short day, short hour, short minute) {
        DateTime dateTime = new DateTime(year, month, day, hour, minute, 0, 0);
        return dateTime.toDate();
    }

    /**
     * 获取某日期 前 后 N天（前 n为负数，后 n为正数）
     *
     * @author xpp
     * @date 2017年3月24日 上午10:40:34
     */
    public static Date getPlusDays(Date date, int n) {
        DateTime dateTime = new DateTime(date);
        DateTime newTime = dateTime.plusDays(n);
        return newTime.toDate();
    }

    /**
     * 获取某日期的 年
     *
     * @author xpp
     * @date 2017年3月24日 上午10:40:34
     */
    public static short year(Date date) {
        DateTime dateTime = new DateTime(date);
        return (short) dateTime.getYear();
    }

    /**
     * 获取某日期的 月
     *
     * @author xpp
     * @date 2017年3月24日 上午10:40:34
     */
    public static short month(Date date) {
        DateTime dateTime = new DateTime(date);
        return (short) dateTime.getMonthOfYear();
    }

    /**
     * 获取某日期的 日
     *
     * @author xpp
     * @date 2017年3月24日 上午10:40:34
     */
    public static short day(Date date) {
        DateTime dateTime = new DateTime(date);
        return (short) dateTime.getDayOfMonth();
    }

    /**
     * 获取某日期的 时
     *
     * @author xpp
     * @date 2017年3月24日 上午10:40:34
     */
    public static short hour(Date date) {
        DateTime dateTime = new DateTime(date);
        return (short) dateTime.getHourOfDay();
    }

    /**
     * 获取某日期的 分
     *
     * @author xpp
     * @date 2017年3月24日 上午10:40:34
     */
    public static short minute(Date date) {
        DateTime dateTime = new DateTime(date);
        return (short) dateTime.getMinuteOfHour();
    }

    /**
     * 获取某日期的 秒
     *
     * @author xpp
     * @date 2017年3月24日 上午10:40:34
     */
    public static short second(Date date) {
        DateTime dateTime = new DateTime(date);
        return (short) dateTime.getSecondOfMinute();
    }

    /**
     * 将字符串的日期转换成Date类型
     *
     * @param date
     * @return
     * @throws ParseException
     * @author xpp
     * @date 2017年5月8日 下午5:29:55
     */
    public static Date getStringFormatToDate(String date) {
        DateTimeFormatter format = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
        DateTime dateTime = DateTime.parse(date, format);
        return dateTime.toDate();
    }

    /**
     * 将字符串(yyyy-MM-dd)的日期转换成Date类型
     * @param dateStr
     * @return
     */
    public static Date YYYYMMDDFormatToDate(String dateStr){
    	if(StringUtils.isNotEmpty(dateStr)){
    		String pattern = "yyyy-MM-dd";
    		return getStringFormatToDate(pattern, dateStr);
    	}
    	return null;
    }

    /**
     * 将字符串(yyyy-MM-dd)的日期转换成Date类型
     * @param dateStr
     * @return
     */
    public static Date YYYYMMDDFormatToStartDate(String dateStr){
    	if(StringUtils.isNotEmpty(dateStr)){
    		String pattern = "yyyy-MM-dd HH:mm:ss";
    		return getStringFormatToDate(pattern, dateStr+" 00:00:00");
    	}
    	return null;
    }

    /**
     * 将字符串(yyyy-MM-dd)的日期转换成Date类型
     * @param dateStr
     * @return
     */
    public static Date YYYYMMDDFormatToEndDate(String dateStr){
    	if(StringUtils.isNotEmpty(dateStr)){
    		String pattern = "yyyy-MM-dd HH:mm:ss";
    		return getStringFormatToDate(pattern, dateStr+" 23:59:59");
    	}
    	return null;
    }

    public static void main(String[] args) {
    	Date startDate = YYYYMMDDFormatToStartDate("2017-06-09");
    	Date endDate = YYYYMMDDFormatToEndDate("2017-06-09");
    	System.out.println(startDate);
    	System.out.println(endDate);
	}

    /**
     * 将字符串的日期转换成Date类型
     * @param pattern
     * @param dateStr
     * @return
     */
    public static Date getStringFormatToDate(String pattern, String dateStr){
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(pattern);
			Date date = sdf.parse(dateStr);
			return date;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
    }


    /**
     * 将当前时间加N分钟
     *
     * @param date
     * @return
     * @author xpp
     * @date 2017年5月8日 下午5:46:53
     */
    public static Date getDateFormatToAddDate(int date) {
        DateTime dateTime = new DateTime();
        return dateTime.plusMinutes(date).toDate();
    }

    /**
     * 两个时间差值(返回的是差的绝对值)
     *
     * @param startCal
     * @param endCal
     * @param key      d:天数，h:小时，m:分钟，s:秒数，默认:毫秒
     * @return
     */
    public static long compareDateByType(Date startDate, Date endDate, char... type) {
        char key = 'd';
        if (type != null && type.length > 0) {
            key = type[0];
        }
        long diffNum = 0;
        DateTime startTime = new DateTime(startDate);
        DateTime endTime = new DateTime(endDate);

        DateTime begin = setDateTimeToStart(startTime, key);
        DateTime end = setDateTimeToStart(endTime, key);

        Duration duration = new Duration(begin, end);
        switch (key) {
            case 'd':
                diffNum = duration.getStandardDays();
                break;
            case 'h':
                diffNum = duration.getStandardHours();
                break;
            case 'm':
                diffNum = duration.getStandardMinutes();
                break;
            case 's':
                diffNum = duration.getStandardSeconds();
                break;
            default:
                diffNum = duration.getMillis();
                break;
        }
        return Math.abs(diffNum);
    }

    /**
     * 设置时间：月日时分秒为2000-01-01 00:00:00
     *
     * @param dateTime
     * @param type     y:年 Ｍ:月 d:天 h:小时 m:分钟
     * @return
     */
    public static DateTime setDateTimeToStart(DateTime dateTime, char key) {
        if (dateTime == null) {
            dateTime = DateTime.now();
        }
        switch (key) {
            case 'y':
                dateTime = dateTime.withMonthOfYear(1).withDayOfMonth(1).withHourOfDay(0).withMinuteOfHour(0)
                        .withSecondOfMinute(0);
                break;
            case 'M':
                dateTime = dateTime.withDayOfMonth(1).withHourOfDay(0).withMinuteOfHour(0).withSecondOfMinute(0);
                break;
            case 'd':
                dateTime = dateTime.withHourOfDay(0).withMinuteOfHour(0).withSecondOfMinute(0);
                break;
            case 'h':
                dateTime = dateTime.withMinuteOfHour(0).withSecondOfMinute(0);
                break;
            case 'm':
                dateTime = dateTime.withSecondOfMinute(0);
                break;
        }
        return dateTime;
    }

    /**
     * 获得本月第一天0点时间
     *
     * @return
     * @author xpp
     * @date 2017年5月8日 下午6:11:28
     */
    public static Date getTimesMonthmorning() {
        Calendar cal = Calendar.getInstance();
        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH));
        return cal.getTime();
    }

    /**
     * 获得本月最后一天24点时间
     *
     * @return
     * @author xpp
     * @date 2017年5月8日 下午6:12:10
     */
    public static Date getTimesMonthnight() {
        Calendar cal = Calendar.getInstance();
        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        cal.set(Calendar.HOUR_OF_DAY, 24);
        return cal.getTime();
    }

    /**
     * 判断时间是否在时间段内
     * @param date
     * @param dateBegin
     * @param dateEnd
     * @return
     */
    public static boolean isInDate(Date date, Date dateBegin, Date dateEnd) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String strDate = sdf.format(date);
        String strDateBegin = sdf.format(dateBegin);
        String strDateEnd = sdf.format(dateEnd);
        // 截取当前时间时分秒
        int strDateH = Integer.parseInt(strDate.substring(11, 13));
        int strDateM = Integer.parseInt(strDate.substring(14, 16));
        int strDateS = Integer.parseInt(strDate.substring(17, 19));
        // 截取开始时间时分秒
		int strDateBeginH = Integer.parseInt(strDateBegin.substring(11, 13));
		int strDateBeginM = Integer.parseInt(strDateBegin.substring(14, 16));
		int strDateBeginS = Integer.parseInt(strDateBegin.substring(17, 19));
        // 截取结束时间时分秒
		int strDateEndH = Integer.parseInt(strDateEnd.substring(11, 13));
		int strDateEndM = Integer.parseInt(strDateEnd.substring(14, 16));
		int strDateEndS = Integer.parseInt(strDateEnd.substring(17, 19));
        if ((strDateH >= strDateBeginH && strDateH <= strDateEndH)) {
            // 当前时间小时数在开始时间和结束时间小时数之间
            if (strDateH > strDateBeginH && strDateH < strDateEndH) {
                return true;
                // 当前时间小时数等于开始时间小时数，分钟数在开始和结束之间
            } else if (strDateH == strDateBeginH && strDateM >= strDateBeginM
                    && strDateM <= strDateEndM) {
                return true;
                // 当前时间小时数等于开始时间小时数，分钟数等于开始时间分钟数，秒数在开始和结束之间
            } else if (strDateH == strDateBeginH && strDateM == strDateBeginM
                    && strDateS >= strDateBeginS && strDateS <= strDateEndS) {
                return true;
            }
            // 当前时间小时数大等于开始时间小时数，等于结束时间小时数，分钟数小等于结束时间分钟数
            else if (strDateH >= strDateBeginH && strDateH == strDateEndH
                    && strDateM <= strDateEndM) {
                return true;
                // 当前时间小时数大等于开始时间小时数，等于结束时间小时数，分钟数等于结束时间分钟数，秒数小等于结束时间秒数
            } else if (strDateH >= strDateBeginH && strDateH == strDateEndH
                    && strDateM == strDateEndM && strDateS <= strDateEndS) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

}
